<template>
  <view class="container">
    <view class="main-content">
      <view class="model-container">
        <!-- 3D模型容器 -->
        <canvas type="webgl" id="threeCanvas" class="three-canvas" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd"></canvas>
        <!-- 点击区域 -->
        <view class="click-areas">
          <view class="click-area head" @click="handlePartClick('head')"></view>
          <view class="click-area body" @click="handlePartClick('body')"></view>
          <view class="click-area feet" @click="handlePartClick('feet')"></view>
        </view>
        <!-- 对话气泡 -->
        <view class="dialog-bubble" v-if="showDialog">
          {{ dialogText }}
        </view>
      </view>
      
      <view class="chat-container">
        <view class="chat-messages" ref="chatMessages">
          <view v-for="(msg, index) in chatMessages" :key="index" :class="['message', msg.type]">
            {{ msg.content }}
          </view>
        </view>
        <view class="chat-input">
          <input type="text" v-model="chatInput" placeholder="输入消息与AI对话" @keyup.enter="sendMessage" />
          <button @click="sendMessage">发送</button>
        </view>
      </view>
    </view>
    
    <view class="cards-container">
      <!-- 药箱入口卡片 -->
      <view class="card medicine-box" @click="navigateToRelation">
        <view class="card-content">
          <text class="card-title">药箱</text>
          <text class="card-desc">查看药品关系图谱</text>
        </view>
        <text class="iconfont icon-arrow-right"></text>
      </view>
      
      <!-- 分类入口卡片 -->
      <view class="card categories" @click="navigateToCategories">
        <view class="card-content">
          <text class="card-title">分类</text>
          <text class="card-desc">按分类查看药品</text>
        </view>
        <text class="iconfont icon-arrow-right"></text>
      </view>
    </view>
    
    <!-- 用药提醒卡片 -->
    <view class="reminder-container" v-if="todayReminders.length > 0">
      <text class="section-title">今日提醒</text>
      <view class="reminder-list">
        <view v-for="(reminder, index) in todayReminders" :key="index" class="reminder-item">
          <text class="reminder-time">{{reminder.time}}</text>
          <text class="reminder-name">{{reminder.medicineName}}</text>
          <text class="reminder-status" :class="reminder.status">{{getReminderStatus(reminder.status)}}</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { ref, onMounted, nextTick, onUnmounted } from 'vue'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import type { MedicineReminder, ChatMessage } from '@/types'

// 3D模型相关
let scene: THREE.Scene | null = null
let camera: THREE.PerspectiveCamera | null = null
let renderer: THREE.WebGLRenderer | null = null
let model: THREE.Group
let mixer: THREE.AnimationMixer
let controls: OrbitControls
let canvas: any = null
let canvasWidth = 0
let canvasHeight = 0

// 对话相关
const showDialog = ref(false)
const dialogText = ref('')
const chatInput = ref('')
const chatMessages = ref<ChatMessage[]>([])

// 初始化 Three.js
const initThree = async () => {
  try {
    // 获取canvas元素和上下文
    const query = uni.createSelectorQuery()
    await new Promise<void>((resolve) => {
      query.select('#threeCanvas')
        .fields({ node: true, size: true })
        .exec((res) => {
          if (res[0]) {
            canvas = res[0].node
            canvasWidth = res[0].width
            canvasHeight = res[0].height
            resolve()
          }
        })
    })

    // 创建场景
    scene = new THREE.Scene()

    // 创建相机
    camera = new THREE.PerspectiveCamera(60, canvasWidth / canvasHeight, 0.1, 1000)
    camera.position.set(0, 2, 5)
    camera.lookAt(0, 0, 0)

    // 创建渲染器
    renderer = new THREE.WebGLRenderer({
      canvas: canvas,
      alpha: true,
      antialias: true
    })
    renderer.setSize(canvasWidth, canvasHeight)
    renderer.setPixelRatio(uni.getSystemInfoSync().pixelRatio)
    renderer.shadowMap.enabled = true
    renderer.shadowMap.type = THREE.PCFSoftShadowMap

    // 添加灯光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.6)
    scene.add(ambientLight)
    
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
    directionalLight.position.set(5, 5, 5)
    directionalLight.castShadow = true
    directionalLight.shadow.mapSize.width = 1024
    directionalLight.shadow.mapSize.height = 1024
    scene.add(directionalLight)

    // 添加轨道控制器
    controls = new OrbitControls(camera, canvas)
    controls.enableDamping = true
    controls.dampingFactor = 0.05
    controls.minDistance = 3
    controls.maxDistance = 10
    controls.maxPolarAngle = Math.PI / 2

    // 加载 GLB 模型
    loadGLBModel()

    // 开始动画渲染
    animate()
  } catch (error) {
    console.error('初始化Three.js失败:', error)
  }
}

// 加载 GLB 模型
const loadGLBModel = () => {
  if (!scene) return
  const loader = new GLTFLoader()
  loader.load('/static/models/character1.glb', (gltf) => {
    model = gltf.scene
    model.scale.set(1.5, 1.5, 1.5)
    model.position.set(0, -1, 0)
    model.traverse((node) => {
      if (node.isMesh) {
        node.castShadow = true
        node.receiveShadow = true
      }
    })
    scene.add(model)

    // 设置动画混合器
    if (gltf.animations.length > 0) {
      mixer = new THREE.AnimationMixer(model)
    }
  }, undefined, (error) => {
    console.error('加载模型失败:', error)
  })
}

// 动画渲染
const animate = () => {
  if (!scene || !camera || !renderer) return
  requestAnimationFrame(animate)

  // 更新轨道控制器
  controls.update()

  // 更新动画混合器
  if (mixer) {
    mixer.update(0.016)
  }

  renderer.render(scene, camera)
}

// 触摸事件处理
const onTouchStart = (event: any) => {
  // 处理触摸开始事件
}

const onTouchMove = (event: any) => {
  // 处理触摸移动事件
}

const onTouchEnd = (event: any) => {
  // 处理触摸结束事件
}

// 生命周期钩子
onMounted(() => {
  nextTick(() => {
    initThree()
  })
})

onUnmounted(() => {
  // 清理资源
  if (renderer) {
    renderer.dispose()
  }
  scene = null
  camera = null
  canvas = null
})

// 处理部位点击
const handlePartClick = (part: string) => {
  let animation: string | undefined
  let text: string

  switch (part) {
    case 'head':
      animation = 'head_nod'
      text = '头部感觉不错！'
      break
    case 'body':
      animation = 'body_wave'
      text = '肚子有点饿了...'
      break
    case 'feet':
      animation = 'feet_dance'
      text = '让我跳个舞！'
      break
    default:
      text = '点击了未知部位'
  }

  // 显示对话气泡
  dialogText.value = text
  showDialog.value = true
  setTimeout(() => {
    showDialog.value = false
  }, 3000)

  // 播放动画
  if (mixer && animation && model) {
    try {
      const clip = model.animations?.find(a => a.name === animation)
      if (clip) {
        const action = mixer.clipAction(clip)
        action.reset().play()
      } else {
        console.warn(`找不到动画: ${animation}`)
      }
    } catch (error) {
      console.error('播放动画时出错:', error)
    }
  }
}

// 发送消息
const sendMessage = async () => {
  if (!chatInput.value.trim()) return

  // 添加用户消息
  const userMessage: ChatMessage = {
    type: 'user',
    content: chatInput.value.trim()
  }
  chatMessages.value.push(userMessage)

  try {
    // TODO: 调用deepseek API
    const response = '这是AI的回复'

    // 添加AI回复
    const aiMessage: ChatMessage = {
      type: 'ai',
      content: response
    }
    chatMessages.value.push(aiMessage)

    // 清空输入
    chatInput.value = ''

    // 滚动到底部
    await nextTick()
    const messagesEl = document.querySelector('.chat-messages')
    if (messagesEl) {
      messagesEl.scrollTop = messagesEl.scrollHeight
    }
  } catch (error) {
    console.error('发送消息失败:', error)
    // 可以添加错误提示
    uni.showToast({
      title: '发送失败，请重试',
      icon: 'none'
    })
  }
}

// 模拟今日提醒数据
const todayReminders = ref([
  { time: '08:00', medicineName: '感冒药', status: 'pending' },
  { time: '12:00', medicineName: '维生素C', status: 'completed' },
  { time: '19:00', medicineName: '钙片', status: 'missed' }
])

// 获取提醒状态文本
const getReminderStatus = (status: string) => {
  const statusMap = {
    pending: '待服用',
    completed: '已服用',
    missed: '已错过'
  }
  return statusMap[status] || ''
}

// 跳转到药品关系图页面
const navigateToRelation = () => {
  uni.navigateTo({
    url: '/pages/medicine/relation'
  })
}

// 跳转到分类药品列表页面
const navigateToCategories = () => {
  uni.switchTab({
    url: '/pages/medicine/list?mode=category'
  })
}

onMounted(() => {
  // TODO: 获取今日提醒数据
})
</script>

<style lang="scss" scoped>
.container {
  padding: 40rpx;
  min-height: 100vh;
  background: #f8f8f8;
}

.main-content {
  display: flex;
  gap: 40rpx;
  margin-bottom: 40rpx;
}

.model-container {
  flex: 1;
  position: relative;
  height: 800rpx;
  background: #ffffff;
  border-radius: 24rpx;
  overflow: hidden;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
}

.three-canvas {
  width: 100%;
  height: 100%;
}

.click-areas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.click-area {
  position: absolute;
  pointer-events: auto;
  cursor: pointer;
}

.head {
  top: 20%;
  left: 50%;
  transform: translateX(-50%);
  width: 100rpx;
  height: 100rpx;
}

.body {
  top: 40%;
  left: 50%;
  transform: translateX(-50%);
  width: 150rpx;
  height: 200rpx;
}

.feet {
  bottom: 10%;
  left: 50%;
  transform: translateX(-50%);
  width: 200rpx;
  height: 100rpx;
}

.dialog-bubble {
  position: absolute;
  top: 20%;
  right: 10%;
  background: #ffffff;
  padding: 20rpx;
  border-radius: 16rpx;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
  animation: fadeIn 0.3s ease-in-out;
}

.dialog-bubble::after {
  content: '';
  position: absolute;
  left: -20rpx;
  top: 50%;
  transform: translateY(-50%);
  border: 10rpx solid transparent;
  border-right-color: #ffffff;
}

.chat-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border-radius: 24rpx;
  padding: 24rpx;
  box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 24rpx;
  margin-bottom: 16rpx;
}

.message {
  margin-bottom: 24rpx;
  padding: 20rpx 24rpx;
  border-radius: 16rpx;
  max-width: 75%;
  font-size: 28rpx;
  line-height: 1.5;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
}

.message.user {
  background: linear-gradient(135deg, #018d71, #016d57);
  color: #ffffff;
  align-self: flex-end;
  margin-left: auto;
  border-bottom-right-radius: 4rpx;
}

.message.ai {
  background: #f8f8f8;
  color: #333333;
  align-self: flex-start;
  margin-right: auto;
  border-bottom-left-radius: 4rpx;
}

.chat-input {
  display: flex;
  gap: 24rpx;
  padding: 20rpx;
  border-top: 2rpx solid #f0f0f0;
  background: #f8f8f8;
  border-radius: 16rpx;
}

.chat-input input {
  flex: 1;
  padding: 20rpx 24rpx;
  border: 2rpx solid #e8e8e8;
  border-radius: 12rpx;
  background: #ffffff;
  font-size: 28rpx;
  transition: all 0.3s ease;
}

.chat-input input:focus {
  border-color: #018d71;
  box-shadow: 0 0 0 2rpx rgba(1, 141, 113, 0.1);
}

.chat-input button {
  padding: 20rpx 40rpx;
  background: linear-gradient(135deg, #018d71, #016d57);
  color: #ffffff;
  border-radius: 12rpx;
  border: none;
  font-size: 28rpx;
  font-weight: 500;
  transition: all 0.3s ease;
  box-shadow: 0 4rpx 12rpx rgba(1, 141, 113, 0.2);
}

.chat-input button:active {
  transform: translateY(2rpx);
  box-shadow: 0 2rpx 8rpx rgba(1, 141, 113, 0.15);
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10rpx);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pet-image {
  width: 300rpx;
  height: 300rpx;
}

.cards-container {
  display: flex;
  gap: 20rpx;
  margin-bottom: 40rpx;
}

.card {
  flex: 1;
  background: #ffffff;
  border-radius: 16rpx;
  padding: 30rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
  
  .card-content {
    .card-title {
      font-size: 32rpx;
      font-weight: bold;
      color: #333333;
      margin-bottom: 8rpx;
    }
    
    .card-desc {
      font-size: 24rpx;
      color: #999999;
    }
  }
  
  .iconfont {
    font-size: 36rpx;
    color: #999999;
  }
}

.reminder-container {
  background: #ffffff;
  border-radius: 16rpx;
  padding: 30rpx;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
  
  .section-title {
    font-size: 32rpx;
    font-weight: bold;
    color: #333333;
    margin-bottom: 20rpx;
  }
}

.reminder-list {
  .reminder-item {
    display: flex;
    align-items: center;
    padding: 20rpx 0;
    border-bottom: 1rpx solid #f5f5f5;
    
    &:last-child {
      border-bottom: none;
    }
    
    .reminder-time {
      font-size: 28rpx;
      color: #333333;
      width: 120rpx;
    }
    
    .reminder-name {
      flex: 1;
      font-size: 28rpx;
      color: #333333;
      margin: 0 20rpx;
    }
    
    .reminder-status {
      font-size: 24rpx;
      padding: 4rpx 16rpx;
      border-radius: 24rpx;
      
      &.pending {
        color: #018d71;
        background: rgba(1, 141, 113, 0.1);
      }
      
      &.completed {
        color: #52c41a;
        background: rgba(82, 196, 26, 0.1);
      }
      
      &.missed {
        color: #f5222d;
        background: rgba(245, 34, 45, 0.1);
      }
    }
  }
}
</style>
